package tr.edu.metu.is550.isell.rest.resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import tr.edu.metu.is550.isell.domain.User;
import tr.edu.metu.is550.isell.domain.UserContactInfo;
import tr.edu.metu.is550.isell.domain.UserCredentials;
import tr.edu.metu.is550.isell.rest.message.GetUserDetailsResponseMessage;
import tr.edu.metu.is550.isell.rest.message.RegisterUserMessage;
import tr.edu.metu.is550.isell.rest.message.UpdateUserMessage;
import tr.edu.metu.is550.isell.service.UserService;

import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Component
@Path("user")
public class UserResource {

    @Autowired
    private UserService userService;

    @GET
    @Path("{username}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('ROLE_USER')")
    public Response getUserDetails(@PathParam("username") String username) {
        GetUserDetailsResponseMessage userDetailsResponseMessage = buildUserDetailsResponseMessage(username);
        return Response.ok().entity(userDetailsResponseMessage).build();
    }

    @GET
    @Path("{username}/{login}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('ROLE_USER') and #username==principal.username")
    public Response login(@PathParam("username") String username) {
        GetUserDetailsResponseMessage userDetailsResponseMessage = buildUserDetailsResponseMessage(username);
        return Response.ok().entity(userDetailsResponseMessage).build();
    }

    @PUT
    @Path("{username}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasRole('ROLE_USER') and #username==principal.username")
    public Response updateUser(@PathParam("username") String username, @Valid UpdateUserMessage updateUserMessage) {

        UserContactInfo contactInfo = new UserContactInfo(updateUserMessage.getName(), updateUserMessage.getSurname(), updateUserMessage.getAddress(), updateUserMessage.getPhone(), updateUserMessage.getEmail());
        UserCredentials userCredentials = new UserCredentials(username, updateUserMessage.getPassword());

        User user = new User(contactInfo, userCredentials);

        userService.updateUser(user);


        return Response.ok().build();
    }


    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response addUser(@Context UriInfo uriInfo, @Valid RegisterUserMessage registerUserMessage) {

        UserContactInfo contactInfo = new UserContactInfo(registerUserMessage.getName(), registerUserMessage.getSurname(), registerUserMessage.getAddress(), registerUserMessage.getPhone(), registerUserMessage.getEmail());
        UserCredentials userCredentials = new UserCredentials(registerUserMessage.getLoginName(), registerUserMessage.getPassword());
        User user = new User(contactInfo, userCredentials);

        user = userService.addUser(user);

        return Response.created(uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getUserCredentials().getLoginName())).build()).build();
    }

    private GetUserDetailsResponseMessage buildUserDetailsResponseMessage(String username) {
        User user = userService.getUser(username);
        return new GetUserDetailsResponseMessage(user.getUserContactInfo().getName(),
                user.getUserContactInfo().getSurname(),
                user.getUserContactInfo().getAddress(),
                user.getUserContactInfo().getPhone(),
                user.getUserContactInfo().getEmail(),
                user.getUserCredentials().getLoginName()
        );
    }
}
